// GUI.cpp: implementation of the GUI class.
//
//////////////////////////////////////////////////////////////////////

#include "GUI.h"
#include "ScenarioCreationState.h"
#include "Menu.h"
#include "SubMenu.h"

// Menus
static char *file_submenu   [] = {  "Exit" ,
									"----" ,
									"Back" ,
									"----" ,
									"Save" ,
									NULL   };
puCallback file_submenu_cb  [] = {  GUI::exit_cb,
									NULL   ,
									GUI::back_cb,
									NULL   ,
									GUI::save_cb, 
									NULL   };

static char *briefing_submenu   [] = { 	"Try movie",
										"Create" , 
										NULL   };
puCallback briefing_submenu_cb  [] = {  GUI::trym_cb,
										GUI::createb_cb, 
										NULL   };

static char *view_submenu   [] = {"Toggle Wireframe" , 
										NULL   };
puCallback view_submenu_cb  [] = {  GUI::togglew_cb, 
									NULL   };

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

GUI::GUI(State *s, LoadingInfo  *li)
{
this->menu = new puMenuBar(-1);
this->menu->add_submenu("File", file_submenu, file_submenu_cb);
this->menu->add_submenu("View", view_submenu, view_submenu_cb);
this->menu->add_submenu("Briefing", briefing_submenu, briefing_submenu_cb);
this->menu->close();
this->menu->hide();
this->menu->setUserData((void*)s);

x_correction = 0.0f;
y_correction = 0.0f;

// player controls
this->player = new puGroup(0,0);
this->player -> setUserData((void*)s);

int sx = (li->w / 2) - (NUM_PLAYER_BUTTONS / 2);

rewindButton	= new puArrowButton(sx							,PLAYER_START_Y,sx + 1*PLAYER_BUTTON_WIDTH,PLAYER_START_Y + PLAYER_BUTTON_HEIGTH,PUARROW_FASTLEFT);
rewindButton	-> setCallback(rewm_cb);
stopButton		= new puArrowButton(sx + 1*PLAYER_BUTTON_WIDTH	,PLAYER_START_Y,sx + 2*PLAYER_BUTTON_WIDTH,PLAYER_START_Y + PLAYER_BUTTON_HEIGTH,PUARROW_DOWN);
stopButton      -> setCallback(stopm_cb);
playButton		= new puArrowButton(sx + 2*PLAYER_BUTTON_WIDTH	,PLAYER_START_Y,sx + 3*PLAYER_BUTTON_WIDTH,PLAYER_START_Y + PLAYER_BUTTON_HEIGTH,PUARROW_RIGHT);
playButton		-> setCallback(playm_cb);
forwardButton	= new puArrowButton(sx + 3*PLAYER_BUTTON_WIDTH	,PLAYER_START_Y,sx + 4*PLAYER_BUTTON_WIDTH,PLAYER_START_Y + PLAYER_BUTTON_HEIGTH,PUARROW_FASTRIGHT);
forwardButton	-> setCallback(ffwdm_cb);

this->player->close();
this->player->hide();

// fill info legends
sprintf(info_text_legend,"\n");
sprintf(camera_east_text_legend,"E : ---\n");
sprintf(camera_north_text_legend,"N : ---\n");
sprintf(camera_h_text_legend,"H : ---\n");
sprintf(camera_p_text_legend,"P : ---\n");
sprintf(camera_r_text_legend,"R : ---\n");
sprintf(camera_heigth_text_legend,"A : ---\n");
sprintf(camera_hot_text_legend,"H : ---\n");
sprintf(pointer_east_text_legend,"E : ---\n");
sprintf(pointer_north_text_legend,"N : ---\n");
sprintf(pointer_hot_text_legend,"H : ---\n");

info = new puText(li->w / 3, 5);
info -> setLabel(info_text_legend);
info -> hide();

this->infoGroup = new puGroup ( 0, 0 ) ;

// create info strings
camera_east = new puText ( (float)(li->w) * (0.90), (int)(0.30 * (float)li->h));
camera_east -> setLabel(camera_east_text_legend);
camera_east -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_north = new puText ( (float)(li->w) * (0.90), (int)(0.28 * (float)li->h));
camera_north -> setLabel(camera_north_text_legend);
camera_north -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_h = new puText ( (float)(li->w) * (0.90), (int)(0.26 * (float)li->h));
camera_h -> setLabel(camera_h_text_legend);
camera_h -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_p = new puText ( (float)(li->w) * (0.90), (int)(0.24 * (float)li->h));
camera_p -> setLabel(camera_p_text_legend);
camera_p -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_r = new puText ( (float)(li->w) * (0.90), (int)(0.22 * (float)li->h));
camera_r -> setLabel(camera_r_text_legend);
camera_r -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_heigth = new puText ( (float)(li->w) * (0.90), (int)(0.20 * (float)li->h));
camera_heigth -> setLabel(camera_heigth_text_legend);
camera_heigth -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

camera_hot = new puText ( (float)(li->w) * (0.90), (int)(0.18 * (float)li->h));
camera_hot -> setLabel(camera_hot_text_legend);
camera_hot -> setColour		 ( PUCOL_LABEL, GUI_CAMERA_COORD_COLOR ) ;

pointer_east = new puText ( (float)(li->w) * (0.90), (int)(0.16 * (float)li->h));
pointer_east -> setLabel(pointer_east_text_legend);
pointer_east -> setColour		 ( PUCOL_LABEL, GUI_POINTER_COORD_COLOR ) ;

pointer_north = new puText ( (float)(li->w) * (0.90), (int)(0.14 * (float)li->h));
pointer_north -> setLabel(pointer_north_text_legend);
pointer_north -> setColour		 ( PUCOL_LABEL, GUI_POINTER_COORD_COLOR ) ;

pointer_hot = new puText ( (float)(li->w) * (0.90), (int)(0.12 * (float)li->h));
pointer_hot -> setLabel(pointer_hot_text_legend);
pointer_hot -> setColour		 ( PUCOL_LABEL, GUI_POINTER_COORD_COLOR ) ;

this->infoGroup->close();
this->infoGroup->reveal();

// Create and load main men˘ buttons
m = new Menu(0.9f,0.9f,2,0.045f,0.06f);

bb = li->buildingButtonsTextures;
tt = li->treeTextures;
ll = li->landTextures;
ww = li->waypointTextures;
mm = li->movieTextures;
ff = li->facilityTextures;

MenuEntry *me = (MenuEntry*)malloc(sizeof(MenuEntry));

me->button = new IconButton(li->textures[ICON_BUTTON_TREES_N],
							li->textures[ICON_BUTTON_TREES_F],
							li->textures[ICON_BUTTON_TREES_C]);
me->submenu = new SubMenu(0.7f,0.9f,2,0.045f,0.06f);
for(int it = 0; it < tt; it++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+li->landTextures+it+li->buildingButtonsTextures]));
	}
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_BUILDINGS_N],
							li->textures[ICON_BUTTON_BUILDINGS_F],
							li->textures[ICON_BUTTON_BUILDINGS_C]);
me->submenu = new SubMenu(0.7f,0.9f,2,0.045f,0.06f);

for(int ib = 0; ib < bb; ib++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+li->landTextures+ib]));
	}
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_TEXTURES_N],
							li->textures[ICON_BUTTON_TEXTURES_F],
							li->textures[ICON_BUTTON_TEXTURES_C]);
me->submenu = new SubMenu(0.7f,0.9f,3,0.045f,0.06f);

for(int il = 0; il < ll; il++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+il]));
	}
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_FACILITIES_N],
							li->textures[ICON_BUTTON_FACILITIES_F],
							li->textures[ICON_BUTTON_FACILITIES_C]);
me->submenu = new SubMenu(0.8f,0.9f,1,0.045f,0.06f);

for(int ifa = 0; ifa < ff; ifa++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+li->landTextures+li->buildingButtonsTextures+li->treeTextures+ifa]));
	}

m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_WAYPOINTS_N],
							li->textures[ICON_BUTTON_WAYPOINTS_F],
							li->textures[ICON_BUTTON_WAYPOINTS_C]);
me->submenu = new SubMenu(0.8f,0.9f,1,0.045f,0.06f);

for(int iw = 0; iw < ww; iw++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+li->landTextures+li->treeTextures+li->buildingButtonsTextures+iw+li->facilityTextures]));
	}
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_BULLDOZER_N],
							li->textures[ICON_BUTTON_BULLDOZER_F],
							li->textures[ICON_BUTTON_BULLDOZER_C]);
me->submenu = NULL;
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_MOVIE_N],
							li->textures[ICON_BUTTON_MOVIE_F],
							li->textures[ICON_BUTTON_MOVIE_C]);
me->submenu = new SubMenu(0.8f,0.9f,1,0.045f,0.06f);

for(int im = 0; im < mm; im++)
	{
	me->submenu->add(new IconButton(li->textures[COUNTRYSIDE_TEXTURES+li->landTextures+li->treeTextures+li->buildingButtonsTextures+li->waypointTextures+li->facilityTextures+im]));
	}
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_SAVE_N],
							li->textures[ICON_BUTTON_SAVE_F],
							li->textures[ICON_BUTTON_SAVE_C]);
me->submenu = NULL;
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_ZOOMIN_N],
							li->textures[ICON_BUTTON_ZOOMIN_F],
							li->textures[ICON_BUTTON_ZOOMIN_C]);
me->submenu = NULL;
m->add(me);
me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_ZOOMOUT_N],
							li->textures[ICON_BUTTON_ZOOMOUT_F],
							li->textures[ICON_BUTTON_ZOOMOUT_C]);
me->submenu = NULL;
m->add(me);

me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_ROTATECW_N],
							li->textures[ICON_BUTTON_ROTATECW_F],
							li->textures[ICON_BUTTON_ROTATECW_C]);
me->submenu = NULL;
m->add(me);
me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_ROTATECCW_N],
							li->textures[ICON_BUTTON_ROTATECCW_F],
							li->textures[ICON_BUTTON_ROTATECCW_C]);
me->submenu = NULL;
m->add(me);
me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_UNDO_N],
							li->textures[ICON_BUTTON_UNDO_F],
							li->textures[ICON_BUTTON_UNDO_C]);
me->submenu = NULL;
m->add(me);
me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_REDO_N],
							li->textures[ICON_BUTTON_REDO_F],
							li->textures[ICON_BUTTON_REDO_C]);
me->submenu = NULL;
m->add(me);
me = (MenuEntry*)malloc(sizeof(MenuEntry));
me->button = new IconButton(li->textures[ICON_BUTTON_EXIT_N],
							li->textures[ICON_BUTTON_EXIT_F],
							li->textures[ICON_BUTTON_EXIT_C]);
me->submenu = NULL;
m->add(me);
}

GUI::~GUI()
{
puDeleteObject(menu);
delete this->m;
puDeleteObject(infoGroup);
puDeleteObject(this->info);
puDeleteObject(this->player);
}

void GUI::show()
{
this->menu->reveal();
}

int GUI::mouse(int button, int state, int x, int y)
{
m->mouse(button,state,x,y);
return m->isFocused();
}

int GUI::getType()
{
return m->getMenuEntry();
}

int GUI::getKind()
{
return m->getSubMenuEntry();
}

void GUI::display()
{
m->display();
//printf("e: %d  --- s: %d\n",m->getMenuEntry(),m->getSubMenuEntry());
}

void GUI::bindTextures()
{
m->bindTextures();
}

void GUI::switchToEditingView()
{
this->menu->reveal();
this->m->reveal();
this->infoGroup->reveal();
this->player->hide();

strcpy(info_text_legend,INFO_GO_TO_CAMERA_REPOSITIONING);
this->info->setLegend(this->info_text_legend);
info->reveal();
}

void GUI::switchToCameraRepositioningView()
{
this->menu->hide();
this->m->hide();
this->infoGroup->hide();

strcpy(info_text_legend,INFO_RETURN_TO_EDITING);
this->info->setLegend(this->info_text_legend);
info->reveal();
}

void GUI::switchToMovieView()
{
this->menu->hide();
this->m->hide();
this->infoGroup->hide();
this->player->reveal();

strcpy(info_text_legend,INFO_STOP_PLAYING_MOVIE );
this->info->setLegend(this->info_text_legend);
info->reveal();
}

void GUI::setCorrection(float x, float y)
{
this->x_correction = x;
this->y_correction = y;
}

void GUI::setData(sgCoord* camera, float hot, float *pointer)
{
sprintf(this->camera_east_text_legend,"E: %01.0f",camera->xyz[SG_X] + x_correction);
this->camera_east->setLegend(this->camera_east_text_legend);

sprintf(this->camera_north_text_legend,"N: %01.0f",camera->xyz[SG_Y] + y_correction);
this->camera_north->setLegend(this->camera_north_text_legend);

sprintf(this->camera_h_text_legend,"H: %01.0f",-camera->hpr[0]);
this->camera_h->setLegend(this->camera_h_text_legend);

sprintf(this->camera_p_text_legend,"P: %01.0f",camera->hpr[1]);
this->camera_p->setLegend(this->camera_p_text_legend);

sprintf(this->camera_r_text_legend,"R: %01.0f",camera->hpr[2]);
this->camera_r->setLegend(this->camera_r_text_legend);

sprintf(this->camera_hot_text_legend,"Hot: %01.0f",hot);
this->camera_hot->setLegend(this->camera_hot_text_legend);

sprintf(this->camera_heigth_text_legend,"Alt: %01.0f",camera->xyz[SG_Z]);
this->camera_heigth->setLegend(this->camera_heigth_text_legend);

sprintf(this->pointer_east_text_legend,"E: %01.0f",pointer[SG_X] + x_correction);
this->pointer_east->setLegend(this->pointer_east_text_legend);

sprintf(this->pointer_north_text_legend,"N: %01.0f",pointer[SG_Y] + y_correction);
this->pointer_north->setLegend(this->pointer_north_text_legend);

sprintf(this->pointer_hot_text_legend,"Hot: %01.0f",pointer[SG_Z]);
this->pointer_hot->setLegend(this->pointer_hot_text_legend);
}

void GUI::exit_cb ( puObject * p)
{
exit(0);
}

void GUI::back_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getParent()->getUserData();
scs->goBack();
}

void GUI::save_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getParent()->getUserData();
scs->saveScenario();
}

void GUI::createb_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getParent()->getUserData();

char fn[1024];

strcpy(fn,scs->info->dem_filename);
bool go = true;
int i = 0;
 
while(go)
	{
	if( !(fn[i] == '\0') && !(fn[i] == '\n') )
		{
		i++;
		}
	else
		{
		go = false;
		fn[i-3] = 'b';
		fn[i-2] = 'r'; 
		fn[i-1] = 'f';
		fn[i] = '\0';
		}
	}

printf("Saving briefing %s\n",fn);


FILE *f;

if( (f=fopen(fn,"w")) != NULL)
	{
	fprintf(f,"%s\n",SCENARIO_FILE_SECTION);
	fprintf(f,"%s\n",scs->info->snr_filename);
	fprintf(f,"%s\n",WORLD_FILE_SECTION);

	char fn[1024];

	strcpy(fn,scs->info->dem_filename);
	bool go = true;
	int i = 0;
 
	while(go)
		{
		if( !(fn[i] == '\0') && !(fn[i] == '\n') )
			{
			i++;
			}
		else
			{
			go = false;
			fn[i-4] = '_';
			fn[i-3] = 'b';
			fn[i-2] = 'r'; 
			fn[i-1] = 'f';
			fn[i-0] = '.';
			fn[i+1] = 'd';
			fn[i+2] = 'e';
			fn[i+3] = 'm';
			fn[i+4] = '\0';
			}
		}
	fprintf(f,"%s\n",fn);

			fn[i+1] = 'b';
			fn[i+2] = 'm';
			fn[i+3] = 'p';
			fn[i+4] = '\0';

	fprintf(f,"%s\n",fn);
	fclose(f);
	}
else
	{
	printf("Cannot open %s briefing file for saving.\n",fn);
	}

}

void GUI::togglew_cb ( puObject * p)
{

}

void GUI::trym_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getParent()->getUserData();

scs->start();
}

void GUI::playm_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getUserData();

scs->play();
}

void GUI::stopm_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getUserData();

scs->stop();
}

void GUI::ffwdm_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getUserData();

scs->forward();
}

void GUI::rewm_cb ( puObject * p)
{
puObject* pr = p->getParent();
ScenarioCreationState* scs = (ScenarioCreationState*) pr->getUserData();

scs->rewind();
}